home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
dicex
/
source
/
dicex.s
< prev
Wrap
Text File
|
1999-05-30
|
25KB
|
999 lines
*********************************************************************
* ASK3アクセサリ DicEx
* Copyright (C) 1996-98 by AIG-Soft
*********************************************************************
.include defines.mac
.include pspdef.mac
.include ask3.mac
*********************************************************************
* 常駐ルーチン
*********************************************************************
* 常駐物なのでメモリー内配置を確定するため、常駐ルーチン内では.text以外は使わない
.text
.even
KEEP_START:
* 常駐確認用識別子
id: .dc.b 'DicEx V2.2',19,99,'AIG-Soft',0
*********************************************************************
* ワーク1
*********************************************************************
* ここに置くワークは、常駐前に初期値が必要な(初期化される)もの
ACCS equ 2 * 組み込むアクセサリの数
.even
ACh .dcb.l ACCS,-1 * アクセサリ(初期値-1<0)
all .dc.l 0 * ワークエリアサイズ
DicList .dc.l 0 * 0=NULL : 辞書名アドレスアドレス
Gakushu .ds.l 1 * 学習モード(0=メモリ,1=ディスク)アドレス
Dics .ds.w 1 * 登録辞書数
dicm .dc.w 0 * 現在参照中の辞書番号
first .dc.b $ff * DicChangeList:初期起動(=0:初期でない,!=0:初期)
fhigh .dc.b $ff * 高位メモリー確保(=0:No,!=0:Yes)
********************************************************************
ErrNotFound: .dc.b 'は見つかりません',0
MesDicSelect: .dc.b '辞書選択',0
.even
********************************************************************
BREAKOFF:
* d0のみ破壊
move.w #-1,-(sp) * read BREAK mode
DOS _BREAKCK
move.w d0,brksts
clr.w -(sp) * BREAK Cut
DOS _BREAKCK
addq.w #2*2,sp
rts
********************************************************************
CalcDicList:
* 入力:d1.w=dicm
* 出力:a2 =DicList[dicm]
* 破壊:d0.l,a2
move.w d1,d0
add.w d0,d0 * *2
add.w d0,d0 * *4
move.l DicList(pc),a2
move.l (a2,d0.w),a2 * dname=DicList[dicm]
rts
DicChangeSub: * d1.w=dicm
* d0-d1,a0-a2破壊
bsr CalcDicList * a2=DicList[dicm(d1.w)]
*
move.l a2,-(sp)
move.l a2,-(sp)
pea 32.w
DOS _KNJCTRL * 辞書名登録
lea 4*3(sp),sp
tst.l d0
bne DERR * goto DERR
*
moveq.l #0,d0 * for .b -> .l
move.l Gakushu(pc),a1
move.b (a1,d1.w),d0 * &Gakushu[dicm]
move.l d0,-(sp)
pea 11.w
DOS _KNJCTRL * 学習モード設定
pea 2.w
DOS _KNJCTRL * 現在の変換モードを記録
move.l d0,d1 * ret保存
pea 0.w
pea 1.w
DOS _KNJCTRL * ASK終了
move.l d1,-(sp) * ret
pea 1.w
DOS _KNJCTRL * ASK再起動
lea 4*7(sp),sp
tst.l d0
beq 17f * -> OK (d0.l=0)
DERR: * ASK再起動エラー(辞書がない時はここでエラーが出る)
lea cbuf(pc),a1 * cbuf
move.l a1,a0 * a0=cbuf
@@: move.b (a2)+,(a1)+ * cbuf <- dname
bne @b
subq.w #1,a1 * cbufのEOSに戻す
lea ErrNotFound(pc),a2
@@: move.b (a2)+,(a1)+ * cbuf <<- "..."
bne @b
*
move.l #kbuf,d0
moveq.l #0,d1 * 通常表示
bsr Str2MEANS * kbuf[Str2MEAN(cbuf,kbuf,0)]=0;
move.l #DF_KWINSTR|CACI_NORMAL,d0 (d0.l<>0)
17: *
rts
**********************************
DicChangeList:
* アクセサリ本体
* 入力:4+2(sp) = BIT16K キーコード
* 出力:d0.w = リターンコード
move.w Dics(pc),d2 * Dics
cmp.w #1,d2 * Dics<=1?
bhi @f * No : Dics>=2
* 辞書が1つの時は何もしない
move.w #CACI_END,d0 * Yes
rts
*
@@: move.w 4+2(sp),d2 * BIT16K キーコード
move.l d3,-(sp) * push d3
move.w #CACI_NORMAL,d3 * ret=規定外キー入力の時のため
*
bsr BREAKOFF
* キーを探して各ルーチンへ飛ぶ
lea Jtable(pc),a0
move.w d2,d1
and.w #NAKEY,d1
@@: move.l (a0)+,d0 * jump|code
beq @f * -> end of table
cmp.w d1,d0 * =code?
bne @b * no
swap d0 * d0=jump
move.w dicm(pc),d1 * dicmを引数とする
jsr -4(a0,d0.w)
*
@@: bsr BREAKON
*
moveq.l #0,d0 * for .w = .l
move.w d3,d0
move.l (sp)+,d3 * pop d3
rts
*------------------------------------
Jtable: * 各キー毎のジャンプテーブル(出てきやすい順に並べる)
* jump先(offset),code
* CTRL+XF3 : 起動/終了
* ↑↓/XF3/SHIFT+XF3 : 内容選択
* CR : 決定&終了
* ESC : 終了
.dc.w xf3key-$,NOT_ASCII|XF3_KEY
.dc.w crkey-$,CR
.dc.w downkey-$,NOT_ASCII|DOWN_KEY
.dc.w upkey-$,NOT_ASCII|UP_KEY
.dc.w esckey-$,ESC
.dc.w 0,0 * end of table
*------------------------------------
crkey: * CR : 決定終了
bsr DicChangeSub * 辞書変更
move.l d0,d3 * ret=...
beq esckey * =0 : end
rts
xf3key: * XF3系
btst.l #B_CTRL_ON,d2 * btstは.b/.lしかないため
beq 1f * CTRL+XF3でない
* CTRL+XF3:起動
tst.b first
bne @f
* 2回目はキャンセルで終了
esckey: * ESC
st first * first=$ff
move.w #CACI_END,d3 * 終了
rts
*
@@: * 起動した -> 変更
clr.b first * first=0(sf firstでも全く同じ;同サイズ/クロック)
*
lea MesDicSelect(pc),a0
move.l #mbuf,d0
moveq.l #1,d1 * 反転表示
bsr Str2MEANS * mbuf[Str2MEAN("辞書選択",mbuf,1)]=0;
*
pea kbuf(pc) * サブ辞書
lea cbuf(pc),a0
pea (a0) * メイン辞書
pea 41.w
DOS _KNJCTRL
lea 4*3(sp),sp
move.w #DF_KWINSTR|DF_MWINSTR|CACI_NORMAL,d3
bra Retcp
1: * CTRL付きでない時は単なる選択
btst.l #B_SHIFT_ON,d2
beq downkey * XF3 = ↓
* SHIFT+XF3 = ↑
upkey: * ↑
subq.w #1,d1 * --dicm
bpl DEX
move.w Dics(pc),d1 * <0の時
subq.w #1,d1 * dicm=Dics-1
bra DEX
*
downkey:* ↓
addq.w #1,d1 * ++dicm
cmp.w Dics(pc),d1 * dicm>=Dics?
blt DEX * no
moveq.l #0,d1 * >=の時
DEX: move.w d1,dicm
move.w #DF_KWINSTR|CACI_NORMAL,d3
* 変換ラインに表示
bsr CalcDicList * a2=DicList[dicm(d1.w)]
move.l a2,a0
Retcp: move.l #kbuf,d0
moveq.l #0,d1 * 通常表示
* 以下サブルーチンにつながる * kbuf[Str2MEAN(a2,kbuf,0)]=0;
Str2MEANS:
* buf[Str2MEAN(mes,buf,mode)]=0
* a0 <- mes
* d0.l <- buf
* d1.l <- mode (0=通常表示,1=反転表示)
move.l d1,-(sp) * mode
move.l d0,-(sp) * buf
pea (a0) * mes
pea 62.w
DOS _KNJCTRL
lea 4*4(sp),sp
move.l -8(sp),a0 * buf
add.w d0,d0 * .w=MEAN
clr.w (a0,d0.w) * buf[..]=0
rts
********************************************************************
DicEXchangeSub:
* d1.w <- dicm
bsr BREAKOFF
bsr DicChangeSub * d1.w=dicm
* 以下サブルーチンにつながる
BREAKON:
* d0のみ破壊
move.w brksts(pc),-(sp)
DOS _BREAKCK
addq.w #2,sp
rts
DicEXchange:
moveq.l #1,d1 * dicm=でも使う
cmp.w Dics(pc),d1 * Dics<=1?
bge 1f
lea dicm(pc),a1
tst.w (a1) * dicm=0?
beq @f * Yes(dicm<-1)
* dicm<>0 -> dicm=0
moveq.l #0,d1
@@: move.w d1,(a1) * dicm=0/1
bsr DicEXchangeSub
1: move.l #CACI_END,d0
rts
*********************************************************************
* ワーク2
*********************************************************************
* ここに置くワークは、常駐後に使われるもの
* これらのワークエリアは常駐後に利用可能になるので、
* 以下の非常駐ルーチンからは参照しないこと
* 常駐後に非常駐部分をワークエリアにする定義
mbufsz equ 2*M_SIZE * .ds.w MSIZE
kbufsz equ 2*K_SIZE * .ds.w K_SIZE
cbufsz equ C_SIZE * .ds.b C_SIZE
mbuf:
kbuf equ mbuf+mbufsz
cbuf equ kbuf+kbufsz
brksts equ cbuf+cbufsz * .ds.w 1
WORK_END equ brksts+2
*********************************************************************
* ワークエリア転送ルーチン
*********************************************************************
* ワークエリアを低位メモリーに取るとき、mallocではなく常駐メモリーを多く取って
* プログラムの後ろに付ける。これは、メモリーの分断を防ぐためである。
*
TrnsWork:
* /hがないとき+常駐終了時のみここにくる
* a0,a2<- 元のDicList
* a1 <- KEEP_END
* d0.l <- ワークエリアサイズ
* d6.l <- 常駐サイズ
* d7.l <- exit code
* 転送
@@: move.b (a0)+,(a1)+ * 元DicList->KEEP_END
dbra d0,@b
* 高位メモリーワーク解放
pea (a2) * DicList
DOS _MFREE
addq.w #4,sp * めんどうなのでエラー処理は省略
ComEnd: * コマンドライン
clr.w -(sp) * exit(0)相当
move.l d6,-(sp) * 常駐サイズ
DOS _KEEPPR
TrnsWorkEnd:
*--------------------------------------------------------------------
* 転送ルーチンがWORK_ENDより小さいときはWORK_ENDがKEEP_END、
* 逆の時はTrnsWorkEndがKEEP_END
* 常駐部分最後
KEEP_END equ WORK_END
* 常駐固定部分最後+1
*********************************************************************
* 非常駐ルーチン
*********************************************************************
* アクセサリ定義構造体
*********************************************************************
.even
ACdef:
* リストから辞書変更
.dc.w KS_EDIT0|KS_EDITING * 仮入力なし/あり
.dc.w CTRL_ON|NOT_ASCII|XF3_KEY * 呼びだしキー:特殊キーにはNOT_ASCIIも付ける
.dc.l DicChangeList
.dc.l cbuf * ASK <-> アクセサリ文字列受け渡し
.dc.l kbuf * 使わないところはNULLでもいいらしい
.dc.l mbuf
* 2つの辞書入れ換え
.dc.w KS_EDIT0|KS_EDITING * 仮入力なし/あり
.dc.w CTRL_ON|NOT_ASCII|XF5_KEY * 呼びだしキー
.dc.l DicEXchange
.dc.l cbuf
.dc.l kbuf
.dc.l mbuf
ACdef_end:
*********************************************************************
* アクセサリ 組み込み/解除/初期化
*********************************************************************
.even
GetTokenSub:
* バッファー内でSPC/TAB/,を飛ばす
* 入力:a1 = 元のバッファー
* 出力:a1 = スキップ後のアドレス
* d0.b = 最後の文字
1: move.b (a1),d0
cmp.b #SPC,d0
beq @f
cmp.b #TAB,d0
beq @f
cmp.b #',',d0
beq @f
rts
@@: addq.l #1,a1
bra 1b
STRCPY2 macro
* セパレーター直前までのコピー
* (a1)+ -> (a4)+
local L2,L1,L0
L1: move.b (a1)+,d0
move.b d0,(a4)+
beq L2 * EOS
cmp.b #SPC,d0
beq L0
cmp.b #TAB,d0
beq L0
cmp.b #',',d0
beq L0
cmp.b #$1a,d0
bne L1
L0: clr.b -1(a4) * EOS
L2: *
.endm
STRLEN2 macro
* セパレーター直前までの長さ取得
* (a1) -> d4
local L1,L0
L1: addq.l #1,d4 * +1
move.b (a1)+,d0
beq L0 * EOS
cmp.b #SPC,d0
beq L0
cmp.b #TAB,d0
beq L0
cmp.b #',',d0
beq L0
cmp.b #$1a,d0
bne L1
L0: *
.endm
TLMAX equ 128 * テキストの1行>96
FGETSs:
* over255バイト対応FGETS+α
* d6 <- fp
* a1 <- line(破壊)
* eof -> d1.b ($00/$ff)
* len -> d0
movem.l d4/d5/d7,-(sp)
moveq.l #0,d7 * len=0
move.l d7,d5 * cc=0
2: pea 1.w
pea (a1)
move.w d6,-(sp)
DOS _READ
lea 10(sp),sp
tst.l d0 * ret
sle d1 * d1 <- eof
ble 1f * <=0
move.b (a1),d4
cmp.b #$1a,d4 * EOF
seq d1 * d1 <- eof
beq 1f
cmp.b #LF,d4 * 改行
beq 1f
addq.l #1,a1 * buf++
addq.l #1,d7 * len++
cmp.l #TLMAX,d7 * maxはTLMAX固定
bcs @f * <max
moveq.l #-1,d0 * バッファーオーバー
bra 3f
@@: move.b d4,d5 * cc=c
bra 2b
*
1: cmp.b #CR,d5
bne @f
* CRLFは両方消す
subq.l #1,d7 * len--
subq.l #1,a1 * buf--
@@: clr.b (a1) * EOS
move.l d7,d0 * len
3: movem.l (sp)+,d4/d5/d7
rts
ReadFile:
* 1行読み込み
* d6 <- fp
* 行先頭文字 -> d0.b
* eof -> d1.b ($00/$ff)
* 行先頭 -> a1
1: lea inpptr(pc),a1
bsr FGETSs
tst.l d0 * len=0?
bne @f * no
* 入力文字数=0の間ループ=空行を飛ばす
tst.b d1 * EOF?
beq 1b * No
*
@@: lea inpptr(pc),a1
bsr GetTokenSub * -> d0.b
cmp.b #';',d0
beq 1b * コメント
tst.b d1 * EOF?
beq @f * No
moveq.l #$1a,d0 * eofがある時は$1aが有るように見せかける
@@: cmp.b #$1a,d0 * EOF?
rts * 判定結果のフラグを持ってリターン
**********************************
DicChangeListInit:
* file open
move.l 4(sp),d0 * fname
movem.l d4-d7/a3-a4,-(sp)
clr.w -(sp)
move.l d0,-(sp) * fname
DOS _OPEN
addq.l #6,sp
moveq.l #1,d7 * return(1)のため
move.w d0,d6 * fp
bmi 11f * file open error
* 準備
move.b #TLMAX,inpptr * テキスト1行長さ
* 辞書数チェック
* [0]には必ず最初の辞書=CONFIGで指定した辞書が入る
pea inpptr+2(opc) * sdic : 実際には使わないので仮のワークを指定
lea mdic(opc),a2 * mdic
pea (a2) * mdic
pea 41.w * 辞書名読み取り -> mdic
DOS _KNJCTRL
lea 4*3(sp),sp
moveq.l #0,d4 * len:辞書ファイル名総長さ
@@: addq.l #1,d4
tst.b (a2)+ * メイン辞書名長
bne @b * strlen(mdic)+1(EOS)
*
moveq.l #1,d5 * Dics : +1 for Config中のASKの分
@@: bsr ReadFile
beq 1f * -> EOF
STRLEN2 * len+=strlen2(buff)
addq.w #1,d5 * Dics++
bra @b
*
1: move.w d5,Dics * 記録
* 辞書の数からワークエリアを確保する
* 必要サイズ:sizeof(unchar *)*Dics+Dics+len
* 確保順 :DicList,Gakushu,DicNames
move.l d4,a2 * len(符号拡張させるためa?を使う)
add.w d5,a2 * +Dics
move.w d5,d0 * Dics
add.w d0,d0 * *2
add.w d0,d0 * *4
add.w d0,a2 * +(Dics*4)
move.l a2,all * 全ワークエリアサイズ保存
move.l a2,-(sp)
move.w #2,-(sp) * ここでは常に高位メモリーに確保する
DOS _MALLOC2
addq.w #6,sp
moveq.l #2,d7 * return(2)のための準備
move.l d0,DicList
ble 10f * メモリー確保エラー
* ワークエリアアドレス確定
move.l d0,a2
move.w d5,d0 * Dics
add.w d0,d0 * *2
add.w d0,d0 * *4
lea (a2,d0.w),a3
move.l a3,Gakushu
lea (a3,d5.w),a4 * DicNames;その先頭アドレスを特に記録する必要はない
* メイン辞書名の転送
move.l a4,(a2)+ * DicList[0]=DicNames
lea mdic(opc),a1 * mdic
@@: move.b (a1)+,(a4)+ * EOSまで
bne @b
* Config.sys分の学習モード読み取り
pea 12.w
DOS _KNJCTRL
addq.l #4,sp
move.b d0,(a3)+ * Gakushu[1]
* ファイル先頭戻し
clr.w -(sp)
pea 0.w
move.w d6,-(sp) * fp
DOS _SEEK
addq.w #8,sp
* 実登録
* a2=&DicList[1] , a3=Gakushu[1] , a4=&DicNames[..]
@@: bsr ReadFile
beq 2f * -> EOF
* 辞書名 , 学習モード
move.l a4,(a2)+ * DicList[Dics]=nm
STRCPY2 * (a1)+ -> (a4)+
bsr GetTokenSub * ->a1
moveq.l #1,d7 * 学習on
cmp.b #'1',d0
beq 3f
moveq.l #0,d7 * 学習off
3: move.b d7,(a3)+ * 指定なし/指定がおかしい時にはoffにする
bra @b
*
2: moveq.l #0,d7 * ret=0
10: move.w d6,-(sp) * fp
DOS _CLOSE
addq.l #2,sp
11: move.l d7,d0
movem.l (sp)+,d4-d7/a3-a4
rts
**********************************
DeleteAcc: *** これはGCCの出力したままではないので注意
* a0=常駐しているルーチンのメモリ管理ポインタ
movem.l d3-d4/a0/a3-a4,-(sp) * a0も保存
move.l 20+4(sp),a3 * ACh : a0を加えたためずれる
move.l 24+4(sp),d0 * **DicList
beq @f * DicList=NULLのとき
move.l d0,-(sp)
DOS _MFREE
addq.w #4,sp
move.l 28+4(sp),a0 * ExAd
moveq.l #0,d1 * 起動時の辞書に戻す
jsr (a0)
@@: moveq.l #0,d4 * ret=0
lea ACnames(pc),a4
moveq.l #ACCS-1,d3 * アクセサリの数 -1 for dbra
?168: tst.l (a3) * if ACh[i]>=0?
bmi ?164 * No
pea MesAcc(OPC)
DOS _PRINT
move.l (a4),-(sp) * ACnames[i]
DOS _PRINT
move.l (a3),-(sp) * ACh[i]
pea 61.w
DOS _KNJCTRL * 削除
lea 16(sp),sp
move.l #-1,(a3) * 削除したの印
lea MesAccDel(OPC),a1 * OK message
tst.l d0
jbeq ?169 * ok
* Error
moveq.l #1,d4 * ret=1
lea ErrCantDelAcc(OPC),a1 * error message
?169: move.l a1,-(sp)
DOS _PRINT
addq.w #4,sp
?164: addq.w #4,a3
addq.w #4,a4
dbra d3,?168
move.l d4,d0 * ret
movem.l (sp)+,d3-d4/a0/a3-a4 * a0も保存
rts
**********************************
AttachAcc: ***
movem.l d3/d5/a3/a4,-(sp)
move.l 20(sp),d3 * fname
* ASK version check
pea 50.w
DOS _KNJCTRL * $ff22
addq.w #4,sp
cmp.l #299,d0
bgt @f
pea ErrASK3(OPC) * ASK ver error
DOS _PRINT
addq.w #4,sp
moveq.l #3,d0 * ret=3
bra ?170
*
@@: move.l d3,-(sp) * fname
bsr DicChangeListInit
addq.w #4,sp
*
moveq.l #1,d2
cmp.l d0,d2
beq ?173
moveq.l #2,d2
cmp.l d0,d2
bne ?172
* case 2
pea ErrCantGetWrk(OPC)
bra @f
* case 1
?173: pea ErrNotFndList(OPC)
DOS _PRINT
move.l d3,-(sp) * fname
DOS _PRINT
addq.w #8,sp
pea CrLf(OPC)
@@: DOS _PRINT
addq.w #4,sp
move.l d2,d0 * ret=1/2
bra ?170 * return
*
?172: move.l #ACdef,d5
lea ACh(pc),a3
lea ACnames(pc),a4
moveq.l #ACCS-1,d3 * アクセサリの数 -1 for dbra
?182: pea MesAcc(OPC)
DOS _PRINT
move.l (a4)+,-(sp) * アクセサリ名
DOS _PRINT
move.l d5,-(sp) * ACdef[i]
pea 60.w
DOS _KNJCTRL
lea 16(sp),sp
cmp.l #-1,d0
bne @f
* error
pea ErrCantAttach(OPC)
DOS _PRINT
pea CrLf(OPC)
DOS _PRINT
pea.l DicEXchangeSub(pc)
move.l DicList(pc),-(sp) * DicList
pea ACh(pc) * 内部ACh
bsr DeleteAcc
lea 4*5(sp),sp
moveq.l #4,d0 * ret=4
bra ?170
*
@@: move.l d0,(a3)+ * ACh[i]=ret
pea MesAttach(OPC)
DOS _PRINT
addq.w #4,sp
add.l #20,d5
dbra d3,?182
*
moveq.l #0,d0 * ret=0
?170: movem.l (sp)+,d3/d5/a3/a4
rts
******************************************************************************
* オプションチェック処理部分に関しては、Oh!X 1992/3のX68000マシン語プログラミングを参照
* この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
.even
chkarg: * コマンドライン解析(a2=コマンドライン)
tst.b (a2)+ * コマンドラインサイズ = 0?
beq usage * Yes -> 引数は必ず必要なので、無い場合は使用法表示
arglp: bsr skipsp * 空白飛ばし
tst.b d0 * end?
beq eos * Yes
* オプションは -? or /?
cmp.b #'-',d0
beq chkopt
cmp.b #'/',d0
beq chkopt
getarg:
* オプション以外の引数は辞書リストファイル名とみなす
* nameにその名前を転送
lea.l name(pc),a3
getarglp:
move.b (a2)+,d0
cmp.b #' ',d0 * SPCがあったら終わり
beq getargeos
cmp.b #TAB,d0 * TABがあったら終わり
beq getargeos
move.b d0,(a3)+
beq eos * EOSを入れたら終了(この後にオプションはない)
bra getarglp
getargeos:
clr.b (a3) * EOS
bra arglp * オプションチェックに戻る
chkopt: * オプションチェック
addq.w #1,a2 * skip '-' or '/'
move.b (a2)+,d0
beq usage * -/のみでオプションがない
or.b #$20,d0 * 小文字化
lea flags-2(pc),a6 * 後で+2するため-2しておく
LL1: addq.w #2,a6
tst.b 1(a6)
beq usage * 全オプションチェック終わり -> 規定外オプション
tst.b (a6) * すでにフラグがセットされている?
bne LL1 * Yes : 飛ばす(2重指定だからbne usageにしてもいい)
cmp.b 1(a6),d0 * オプションチェック
bne LL1 * 不一致
st.b (a6) * セット
bra arglp * コマンドライン処理へ戻る
skipsp: * 空白飛ばし
move.b (a2)+,d0
cmp.b #' ',d0
beq skipsp
cmp.b #TAB,d0 * TAB
beq skipsp
subq.w #1,a2 * a2が1つ進んでいるので戻す
eos: rts
*********************************************************************
* メイン
*********************************************************************
.xref keepchk
.xref _ChkEX68
main:
move.l sp,oldstack * 元のスタック保存
lea initsp(pc),sp * 初期化中用のスタックに設定
* PROGRAM=の時スタックオーバーを起こすのでスタックを変更する
* タイトル表示
move.w #2,-(sp) * STDERR
pea title(pc) * 文字列
DOS _FPUTS * エラー出力へ
addq.l #2+4,sp
*
jbsr _ChkEX68 * EX68のチェック
bne Err_EX68 * 動作不可とする(将来外す可能性はある)
*
move.l #(id-KEEP_START),-(sp) * 識別子の相対位置
pea.l (a0) * 自分のメモリ管理ポインタ
bsr keepchk * 常駐チェック
lea 4*3(sp),sp
move.b d0,d7 * d7 :0=常駐してない , -1=常駐している
bsr chkarg * コマンドライン引数チェック
tst.b rflag * -r : 常駐解除?
beq keep * no
remove: * 常駐解除
tst.b d7 * 常駐している?
beq Err_NoKp * No -> error
* a0=常駐しているルーチンのメモリ管理ポインタ
* メモリー管理ポインタを飛ばし、ユーザープログラム先頭へ
* さらに、ACh/DicListまで飛ばす
pea DicEXchangeSub-KEEP_START+PSPSIZ(a0) * DicEXchangeSubのアドレス
*
lea fhigh-KEEP_START+PSPSIZ(a0),a4 * fhighのアドレス
tst.b (a4) * ワークは高位メモリー?
bne @f * Yes
* 低位メモリー
clr.l -(sp) * DicList=NULL:解放しない
bra 1f
*
@@: lea DicList-KEEP_START+PSPSIZ(a0),a4 * 高位メモリーワーク解放
move.l (a4),-(sp) * DicListのアドレス
1: pea ACh-KEEP_START+PSPSIZ(a0) * AChのアドレス
bsr DeleteAcc * アクセサリ解除
lea 12(sp),sp
tst.l d0
bne Err_Kai * アクセサリ登録削除不可により常駐解除不可
pea.l MPSIZ(a0)
DOS _MFREE * プログラム本体のメモリー解放
addq.w #4,sp
tst.l d0
bmi Err_Kai * なぜかメモリー解放出来ない時
* 常駐解除正常終了
pea.l Mesrelease(pc)
DOS _PRINT
addq.w #4,sp
clr.w -(sp) * exit(0)
DOS _EXIT2
keep: * 常駐
tst.b d7 * 常駐している?
bne Err_DBL * Yes -> error(2重常駐)
* プログラム起動時にはフリーエリアの全てが起動プログラムに割り当てられているため、
* これを必要部分以外解放する。そうしないとMALLOCが効かない。
* a0=プログラムメモリ管理ポインタ
* a1=プログラム終了アドレス+1(.data,.bssを含む)
lea MPSIZ(a0),a0 * メモリー管理ポインタ分を飛ばす
move.l a0,ProcAD * このプロセスの先頭アドレス保存
sub.l a0,a1 * 当プログラムサイズ
move.l a1,-(sp) * 確保する領域サイズ
move.l a0,-(sp) * 確保する領域の先頭アドレス
DOS _SETBLOCK * 空き領域確保
addq.w #4*2,sp
tst.l d0
bmi Err_Mem * 領域が確保できない時=エラー
*
lea name(OPC),a2 * 辞書リストファイル名
tst.b (a2)
beq Err_NoList * 辞書リスト指定がない
pea (a2) * 辞書リストファイル名
bsr AttachAcc * アクセサリ組み込み
addq.w #4,sp
tst.l d0
bne Err_Keep * 組み込みエラー
*
* アクセサリも組み込みOK
pea MesKeep(OPC)
DOS _PRINT
addq.w #4,sp
* 常駐終了
move.l oldstack(pc),sp * スタックを戻す
* スタックを戻すのでこれ以降、深いスタックを使わないこと
move.l #KEEP_END-KEEP_START,d6 * 基本常駐サイズ
tst.b hflag * 高位メモリー?
bne ComEnd * Yes
* 低位メモリーの時
clr.b fhigh * 低位メモリー確保の印
* ワークエリアアドレス変更
* このプロセスの占めるメモリー領域を拡大してワークも入るようにする
add.l all(pc),d6 * +ワークエリアサイズ
move.l d6,d0
add.l #PSPSIZ-MPSIZ,d0 * SETBLOCKにはプロセス管理ポインタ分も含める
move.l d0,-(sp) * new size
move.l ProcAD(pc),-(sp)
DOS _SETBLOCK
addq.w #8,sp
bmi Err_Mem * メモリー不足
*
* TrnsWorkを小さくするために、前処理をできるだけこちらに置いている
* ワークエリアポインターを変更
move.l DicList(pc),a2 * 元のDicList
lea KEEP_END(pc),a1
move.l a1,DicList * DicListをKEEP_ENDに変更
move.w Dics(pc),d1
move.w d1,d0
add.w d0,d0
add.w d0,d0 * Dics*4
lea (a1,d0.w),a1 * 新Gakushu
move.l a1,Gakushu
lea (a1,d1.w),a4 * 新DicNames
lea (a2,d0.w),a3 * 旧Gakushu
lea (a3,d1.w),a3 * 旧DicNames
* DicListの各内容も変更
subq.l #1,d1 * -1 for dbra
move.l a2,a0
@@: move.l (a0),d0 * 移動前のアドレス
sub.l a3,d0 * オフセット化
add.l a4,d0 * 新アドレス化
move.l d0,(a0)+
dbra d1,@b
*
lea KEEP_END(pc),a1 * (a0) -> (a1)
move.l a2,a0 * a0=a2=元のDicList
move.l all(pc),d0 * サイズ
subq.l #1,d0 * -1 for dbra
bra TrnsWork
*
* エラー処理
*
Err_EX68: * EX68上である
lea.l ErrEX68(pc),a0
bra.s error
Err_Mem: * メモリーが不足している
lea.l ErrCantGetWrk(OPC),a0 * エラーメッセージの流用
bra error
Err_NoList: * 辞書リスト指定がない
lea.l ErrNoList(pc),a0
bra error
Err_NoKp: * 常駐していないのに解除しようとした
lea.l ErrNoKeep(pc),a0
bra error
Err_DBL: * 2重常駐
lea.l ErrAlreadyKeep(pc),a0
bra error
Err_Keep: * 常駐できない
lea.l CantKeep(pc),a0
bra.s error
Err_Kai: * 常駐解除不可
lea.l ErrCantRelease(pc),a0
bra error
usage: * 使用法
lea.l MesUsage(pc),a0
error:
move.w #2,-(sp) * STDERR
pea.l (a0)
DOS _FPUTS * 標準出力へ
addq.l #2+4,sp
move.w #2,-(sp) * exit(2)
DOS _EXIT2
******************************************************************************
* メッセージ&フラグ
******************************************************************************
.even
flags: * work,フラグキャラクター
rflag .dc.b 0,'r' * 常駐解除フラグ
hflag .dc.b 0,'h' * 高位メモリー確保フラグ
.dc.b 0,0 * end of tabel
ACnames: * メッセージアドレス表
.dc.l AccDicList
.dc.l AccDicEx
AccDicList: .dc.b '辞書リスト選択',0
AccDicEx: .dc.b '辞書入れ換え',0
MesAcc: .dc.b 'アクセサリ「',0
MesAccDel: .dc.b '」を削除しました',CR,LF,0
ErrCantDelAcc: .dc.b '」が削除できません',CR,LF,0
ErrASK3: .dc.b 'ASK v3/codeAではありません',CR,LF,0
ErrNoList: .dc.b '辞書リストファイル指定がない',CR,LF,0
ErrNotFndList: .dc.b '辞書リストファイルが見つかりません:',0
ErrCantGetWrk: .dc.b 'ワークエリアが確保できません',CR,LF,0
ErrCantAttach: .dc.b '」が登録できません',CR,LF,0
MesAttach: .dc.b '」を登録しました' * CrLfにつながる
CrLf: .dc.b CR,LF,0
title: .dc.b 'ASK3/codeAアクセサリ DicEx V2.2',CR,LF
.dc.b TAB,'Copyright 1996-99 by AIG-Soft',CR,LF,0
MesKeep: .dc.b '常駐しました',CR,LF,0
Mesrelease: .dc.b '常駐解除しました',CR,LF,0
ErrNoKeep: .dc.b '常駐していません',CR,LF,0
ErrAlreadyKeep: .dc.b 'すでに常駐しています',CR,LF,0
CantKeep: .dc.b '常駐できません',CR,LF,0
ErrCantRelease: .dc.b '常駐解除できません',CR,LF,0
MesUsage: .dc.b 'DicEx [/H /R] 辞書リストファイル名',CR,LF,0
ErrEX68 .dc.b 'EX68上では組み込めません',CR,LF,0
.even
******************************************************************************
* 非常駐ルーチンが使うワークとスタック
******************************************************************************
.bss
.even
ProcAD .ds.l 1 * このプロセスの先頭アドレス
oldstack .ds.l 1 * 元のスタック
name .ds.b 255 * 辞書リストファイル名
*
inpptr .ds.b TLMAX+1
mdic .ds.b 96 * メイン辞書名
*
.stack
.even
.ds.l 512 * 初期化時に使うスタック
initsp:
******************************************************************************
.end main